/*
 * pwm.c
 *
 *  Created on: 2015-03-08
 *      Author: root
 */

#include "pwm.h"
//#include "uart.h"
#include "definitions.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "inc/hw_ints.h"

int _frequency = 0;
int _period = 1;
int _duty = 10;
int _onOff = 0;
//int _PWM = 0x04;

/*
void initPWM(int freq)
{
	ROM_GPIOPinConfigure(GPIO_PF0_T0CCP0);
	ROM_GPIOPinTypeTimer(GPIO_PORTF_BASE, PF_0);

	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER5);
	ROM_TimerConfigure(TIMER5_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM);

	_period = (ROM_SysCtlClockGet() / freq);

	ROM_TimerLoadSet(TIMER5_BASE, TIMER_A, _period-_duty-1);
	ROM_TimerMatchSet(TIMER5_BASE, TIMER_A, _duty);

	ROM_TimerIntClear(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
	ROM_TimerIntEnable(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
	ROM_IntEnable(INT_TIMER5A);
	ROM_TimerEnable(TIMER5_BASE, TIMER_A);

	bt_UARTsend("pwm initialized\r\n");

}
*/
void initPWM(int freq)
{
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, PF_0);
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, PA_2);


	//bt_UARTsend("PWM Loaded\r\n");
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER5);
	ROM_TimerConfigure(TIMER5_BASE, TIMER_CFG_A_PWM);

	_period = ROM_SysCtlClockGet()/freq;
	ROM_TimerLoadSet(TIMER5_BASE, TIMER_A, _period-1);

	//PWM interrupt setup
	ROM_TimerIntClear(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
	ROM_TimerIntEnable(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
	ROM_TimerControlEvent(TIMER5_BASE, TIMER_A, TIMER_TIMA_TIMEOUT);
	ROM_IntEnable(INT_TIMER5A);
	ROM_TimerEnable(TIMER5_BASE, TIMER_A);
	bt_UARTsend("Init PWM");
	loading_bar(27);
	load_okfail(1);
}

void pwmHandler(void)
{
	//FIXME
	//set _onOff ^= PWM where PWM is macro

	_onOff ^= 0xff;	//Currently for PA_2
	//bt_UARTsend("P");

	//first run, time = duty, second run, time = period - duty
	if (_onOff)
	{
		ROM_TimerLoadSet(TIMER5_BASE, TIMER_A, _duty);
		//bt_UARTsend("O");
	}
	else
	{
		ROM_TimerLoadSet(TIMER5_BASE, TIMER_A, _period-_duty);
		//bt_UARTsend("F");
	}
	//bt_UARTputc(48+_onOff);

	//write out state
	ROM_GPIOPinWrite(GPIO_PORTA_BASE, _PWM, _onOff);
	//ROM_GPIOPinWrite(GPIO_PORTF_BASE, redled, _onOff);
	//ROM_GPIOPinWrite(GPIO_PORTA_BASE, PA_2, _onOff);
	//clear interrupts
	ROM_TimerIntClear(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
	//bt_UARTsend("pwm fire\r\n");
}

void pwmSetDuty(int duty_cycle)
{
	if(duty_cycle > 999)
	{
		duty_cycle = 999;
	}
	if(duty_cycle < 1)
	{
		duty_cycle=1;
	}
	duty_cycle = duty_cycle*_period;
	_duty = duty_cycle/1000;
}


void belt_driver(int direction)
{
	gBeltRunning=direction;
	switch(direction)
	{
	case 0: {
		ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), 0);
		ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), 0);
	} break;
	case 1: {
		ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), IA);
		ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), 0);
	} break;
	case 2: {
		ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), 0);
		ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), IB);
	} break;
	default: {
		ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), 0);
		ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), 0);
	} break;
	}
}
